package de.tum.wi.som.prio.impl;

import java.util.Arrays;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.List;

import de.tum.wi.som.Node;
import de.tum.wi.som.Project;
import de.tum.wi.som.prio.PriorityRule;
import de.tum.wi.som.util.PrioUtil;

public class MaximumSlack implements PriorityRule{

	@Override
	public void prioritize(Project project) {		
		project.calcProjectGraph();
		Node[] nodes = project.getNodes();
		Node source = project.getSource();
		
		// sort by maximum slack
		List<Node> remainingNodes = new ArrayList<Node>();
		remainingNodes.addAll(Arrays.asList(nodes));
		List<Node> scheduledNodes = new ArrayList<Node>();
		List<Node> accessibleNodes;
		Node dummyNode = new Node(0, new int[0]);
		Node candidateNode;
		
		double maxSlack;
		while (!remainingNodes.isEmpty()) {
			accessibleNodes = PrioUtil.determineAccesibleNodes(scheduledNodes, source, remainingNodes);
            if (accessibleNodes.size() == 0) {
            	System.err.println("No accessible nodes found in MaximumSlack");
            	return;
            }
            candidateNode = dummyNode;
			maxSlack = Double.NEGATIVE_INFINITY;
			Iterator<Node> it = accessibleNodes.iterator();
			while(it.hasNext()){
				Node currentNode = it.next();
				if (candidateNode == dummyNode || currentNode.getSlack() > maxSlack){
					maxSlack = currentNode.getSlack();
					candidateNode = currentNode;
				}
			}
			scheduledNodes.add(candidateNode);
			remainingNodes.remove(candidateNode);
		}
		
		project.setNodes(scheduledNodes.toArray(new Node[scheduledNodes.size()]));

		
	}

	@Override
	public String toString(){
		return "MaximumSlack";
	}
}
